/**
 * 
 */
package com.google.code.netz.wfe;

import com.google.code.netz.wfe.api.WorkflowException;
import com.google.code.netz.wfe.events.CaseEvent;
import com.google.code.netz.wfe.events.EventManager;
import com.google.code.netz.wfe.events.WorkItemEvent;
import com.google.code.netz.wfe.events.CaseEvent.CaseEventType;
import com.google.code.netz.wfe.events.WorkItemEvent.WorkItemEventType;
import com.google.code.netz.wfe.model.ICase;
import com.google.code.netz.wfe.model.State;
import com.google.code.netz.wfe.model.WorkItem;

/**
 * @author <a href='mailto:rahul.thakur.xdev@gmail.com'>Rahul Thakur</a>
 * @since 1.0
 * @version $Id$
 */
public class WorkItemLifecycleHandler extends AbstractLifecycleHandler<WorkItem<?>> {

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.google.code.netz.wfe.AbstractLifecycleHandler#handleResume(com.google
	 *      .code.netz.wfe.api.IManaged, java.lang.Object)
	 */
	@Override
	protected void handleResume(WorkItem<?> entity, Object workflowContext) throws WorkflowException {
		// Resume WorkItem only if it is suspended
		if (entity.getCurrentState() == State.STATE_SUSPENDED) {
			entity.setCurrentState(State.STATE_RUNNING);
			EventManager.getInstance().dispatchEvent(
					new WorkItemEvent<WorkItem>(entity, WorkItemEventType.WORKITEM_OPENED));
		} else
			throw new WorkflowException(String.format(
					"WorkItem %s could not be resumed, it is not in a suspended state.", entity));

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.google.code.netz.wfe.AbstractLifecycleHandler#handleStart(com.google
	 *      .code.netz.wfe.api.IManaged, java.lang.Object)
	 */
	@Override
	protected void handleStart(WorkItem<?> entity, Object workflowContext) throws WorkflowException {
		// NOTE: We allow slight leniency for WorkItem to be started off from
		// DEFAULT state since there is no ENABLED state for them yet.
		if (entity.getCurrentState() == State.STATE_DEFAULT || entity.getCurrentState() == State.STATE_ENABLED) {
			entity.setCurrentState(State.STATE_RUNNING);
			EventManager.getInstance().dispatchEvent(
					new WorkItemEvent<WorkItem>(entity, WorkItemEventType.WORKITEM_OPENED));
		} else
			throw new WorkflowException(String.format(
					"WorkItem %s could not be started, it is not in an enabled state.", entity));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.google.code.netz.wfe.AbstractLifecycleHandler#handleStop(com.google
	 *      .code.netz.wfe.api.IManaged, java.lang.Object)
	 */
	@Override
	protected void handleStop(WorkItem<?> entity, Object workflowContext) throws WorkflowException {
		// if the WorkItem completed without error then the state should be set
		// to COMPLETED else should be set to ERROR
		if (entity.getCurrentState() == State.STATE_RUNNING) {
			entity.setCurrentState(State.STATE_COMPLETED);
			EventManager.getInstance().dispatchEvent(
					new WorkItemEvent<WorkItem>(entity, WorkItemEventType.WORKITEM_CLOSED));
		} else
			throw new WorkflowException(String.format("WorkItem %s could not be stopped, it is not currently running.",
					entity));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.google.code.netz.wfe.AbstractLifecycleHandler#handleSuspend(com.google
	 *      .code.netz.wfe.api.IManaged, java.lang.Object)
	 */
	@Override
	protected void handleSuspend(WorkItem<?> entity, Object workflowContext) throws WorkflowException {
		if (entity.getCurrentState() == State.STATE_RUNNING) {
			entity.setCurrentState(State.STATE_SUSPENDED);
			EventManager.getInstance().dispatchEvent(
					new WorkItemEvent<WorkItem>(entity, WorkItemEventType.WORKITEM_SUSPENDED));
		} else
			throw new WorkflowException(String.format(
					"WorkItem %s could not be suspended, it is not currently running.", entity));
	}

}
